package report3.classes;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.Scanner;

/**
 * 分页存储
 * Author：zouran
 * Date：2023/5/4  15:17
 */
public class Page {
    //随机生成的块号区间,[0,range-1]
    private static final Integer range = 11;
    //页表项对应关系
    private final Map<Integer, Integer> map = new HashMap<>();
    //随机页面数组
    private final int[] randPageSizeList = {1, 2, 4};
    //页面大小
    private Integer pageSize;
    //页表项个数
    private Integer count;

    public Page() {
    }

    public void setCount(Integer count) {
        this.count = count;
    }

    public Integer getPageSize() {
        return pageSize;
    }

    public void setPageSize(Integer pageSize) {
        this.pageSize = pageSize;
    }

    //随机生成页面大小
    public void setRandPageSize() {
        Random random = new Random();
        this.pageSize = randPageSizeList[random.nextInt(randPageSizeList.length)];
    }

    //判断块号是否已经存在
    public boolean containsValue(int value) {
        return map.containsValue(value);
    }

    //根据块号找页号
    public int findPage(int value) {
        for (Integer key : map.keySet()) {
            if (map.get(key) == value) {
                return key;
            }
        }
        return 0;
    }

    //随机生成映射关系
    public void randMap() {
        int i = 0;
        while (i < count) {
            Random random = new Random();
            int value = random.nextInt(range);
            if (!containsValue(value)) {
                map.put(i, value);
                System.out.println("请输入第" + i + "页的块号：" + value);
                i++;
            } else {
                System.out.println("请输入第" + i + "页的块号：" + value);
                System.out.printf("随机输入的块号有误，与第%d号页面输入的块号重复，请重新输入第%d号页面对应的块号！\n", findPage(value), i);
            }
        }
    }

    //读入用户输入的映射关系
    public void readScannerMap() {
        int i = 0;
        while (i < count) {
            System.out.printf("请输入第%d页的块号:", i);
            Scanner scanner = new Scanner(System.in);
            int value = scanner.nextInt();
            if (containsValue(value)) {
                System.out.printf("您输入的块号有误，与第%d号页面输入的块号重复，请重新输入第%d号页面对应的块号！\n", findPage(value), i);
            } else {
                map.put(i, value);
                i++;
            }
        }
    }

    /**
     * 计算位置信息
     * 返回集合
     * {
     * page:页
     * Offset:偏移位置
     * status:位置是否合法
     * position:物理
     * }
     */
    public Map<String, Integer> calculate(int position) {
        Map<String, Integer> map1 = new HashMap<>();
        //
        if (position < 0 || position >= count * pageSize) {
            map1.put("status", 0);
            return map1;
        }
        int page = position / pageSize;
        int offset = position % pageSize;
        map1.put("page", map.get(page));
        map1.put("offset", offset);
        map1.put("position", map.get(page) * pageSize + offset);
        map1.put("status", 1);
        return map1;
    }

    //输出快表映射关系
    public void printMap() {
        for (Integer key : map.keySet()) {
            System.out.println(key + "\t" + map.get(key));
        }
    }
}
